package com.evendai.sipdemo.sip

import android.annotation.SuppressLint
import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.os.Message
import android.os.PowerManager
import com.evendai.loglibrary.Timber
import com.evendai.sipdemo.App
import com.evendai.sipdemo.EventBusEventType
import com.evendai.sipdemo.Keys
import com.evendai.sipdemo.PersistentVariables
import com.evendai.sipdemo.bean.EnterMeetingReplyMessage
import com.evendai.sipdemo.bean.GetVersion
import com.evendai.sipdemo.bean.MeetingMessage
import com.evendai.sipdemo.bean.SipMessage
import com.evendai.sipdemo.camera.CameraActivity
import com.evendai.sipdemo.sip.audio.OutgoingService
import com.evendai.sipdemo.sip.audio.TalkbackGroupHelper
import com.evendai.sipdemo.sip.helper.EngineHelper
import com.evendai.sipdemo.sip.helper.SipRegisterHelper
import com.evendai.sipdemo.util.ActivityUtil
import com.evendai.sipdemo.util.JsonUtil
import com.evendai.sipdemo.util.SipUtil
import com.evendai.sipdemo.util.Utils
import org.doubango.Whats
import org.doubango.ngn.NgnEngine
import org.doubango.ngn.events.*
import org.doubango.ngn.media.NgnMediaType
import org.doubango.ngn.model.NgnHistoryEvent
import org.doubango.ngn.model.NgnHistorySMSEvent
import org.doubango.ngn.sip.NgnAVSession
import org.doubango.ngn.sip.NgnMsrpSession
import org.doubango.ngn.utils.NgnConfigurationEntry
import org.doubango.ngn.utils.NgnStringUtils
import org.doubango.ngn.utils.NgnUriUtils
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.jetbrains.anko.startActivity
import org.jetbrains.anko.toast

/** Sip事件处理器  */
class SipEventProcessor: Handler.Callback {

    private val mWakeLock: PowerManager.WakeLock
    private val mEngine = NgnEngine.getInstance()
    /** 是否正在注册 */
    private var isRegistering = false
    /** 是否正在解除注册 */
    private var isUnregistering = false
    private var registerHandler: Handler = Handler(Looper.getMainLooper(), this)
    private var retryCount = 0
    private var isRegisterOk = false
    private var alertDialog: AlertDialog? = null

    init {
        val powerManager = App.getContext().getSystemService(Context.POWER_SERVICE) as PowerManager
        @Suppress("DEPRECATION")
        mWakeLock = powerManager.newWakeLock(PowerManager.ON_AFTER_RELEASE or PowerManager.SCREEN_BRIGHT_WAKE_LOCK or PowerManager.ACQUIRE_CAUSES_WAKEUP, "cn.dazhou:SipEventProcessor")
        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this)
        }
    }

    /** 处理Sip消息事件  */
    fun processMessageEvent(intent: Intent) {
        val args = intent.getParcelableExtra<NgnMessagingEventArgs>(NgnMessagingEventArgs.EXTRA_EMBEDDED)
        if (args == null) {
            Timber.e("Invalid event args")
            return
        }

        if (args.eventType == NgnMessagingEventTypes.INCOMING) {
            if (args.payload == null || args.payload.isEmpty()) return
            val responseString: String
            try {
                responseString = String(args.payload).trim()
            } catch (e: Throwable) {
                Timber.e(e, "收到了消息，但消息内容(args.getPayload())无法转换为String")
                return
            }
            val remoteParty = intent.getStringExtra(NgnMessagingEventArgs.EXTRA_REMOTE_PARTY)
            val date = intent.getStringExtra(NgnMessagingEventArgs.EXTRA_DATE)
            val sipMessage = JsonUtil.json2Bean(responseString, SipMessage::class.java)
            Timber.e("收到消息事件，type = ${args.eventType}, 消息内容：$responseString, remoteParty = $remoteParty, date = $date, sipMessage = $sipMessage")
            when {
                responseString.contains("\"type\":\"kick\"") -> processExitGroup(responseString)
                responseString.contains("\"action\":\"new\"") -> TalkbackGroupHelper.enterGroup(responseString)
                responseString.contains("\"action\":\"getAppVersion\"") -> sendVersion(remoteParty)
                responseString.contains("\"action\":\"getVideoSize\"") -> sendVideoSize(remoteParty)
                responseString.contains("\"action\":\"setVideoSize\"") -> setVideoSize(responseString)
                responseString.contains("\"action\":\"getCoordinate\"") -> sendGps(remoteParty, responseString)
                responseString.contains("\"action\":\"setBallDate\"") -> setTime(responseString)
                responseString.contains("\"action\":\"uploadLog\"") -> uploadLog(responseString)
                responseString.contains("\"action\":\"getSimSerialNumber\"") -> sendSerialNumber(remoteParty)
//                responseString.contains("\"action\":\"restartApp\"") -> App.restartApp()
                responseString.contains("\"action\":\"rotate180\"") -> rotate(180)
                responseString.contains("\"action\":\"rotate0\"") -> rotate(0)
                responseString.contains("\"action\":\"changeMeetingType\"") -> processMeetingType(responseString, remoteParty)
                responseString.contains("\"action\":\"getFile\"") -> processGetFile(responseString)
                responseString.contains("\"action\":\"showLog\"") -> showLog(responseString)
                sipMessage?.action == MeetingMessage.ENTER_MEETING_ACTION -> enterMeeting(responseString) // 进入会议
                sipMessage?.action == MeetingMessage.EXIT_MEETING_ACTION -> exitMeeting(responseString)   // 退出会议
                sipMessage?.action == EnterMeetingReplyMessage.ACTION -> enterMeetingReply(responseString)// 进入会议响应
            }
        }
    }

    private fun enterMeeting(json: String) {
        val meetingMessage = JsonUtil.json2Bean(json, MeetingMessage::class.java)
        if (meetingMessage == null) {
            Timber.fe(Exception("MeetingMessage消息无法解析，json = $json"))
            return
        }

        val fromDisplayName = meetingMessage.fromDisplayName
        val meetingNumber = meetingMessage.meetingNumber
        if (alertDialog != null && alertDialog!!.isShowing) {
            alertDialog!!.cancel()
        }

        val activity = ActivityUtil.getTopActivity() ?: ActivityUtil.getAnyActivity()
        alertDialog = AlertDialog.Builder(activity)
                .setTitle("提示")
                .setMessage("${fromDisplayName}邀请您进入${meetingNumber}会议")
                .setNegativeButton("拒绝邀请") { _, _ -> enterMeeting(meetingMessage, false) }
                .setPositiveButton("接受邀请") { _, _ -> enterMeeting(meetingMessage, true) }
                .setCancelable(false)
                .show()
    }

    private fun enterMeeting(meetingMessage: MeetingMessage, isAccept: Boolean) {
        val enterMeetingReplyMessage = EnterMeetingReplyMessage(
                isAudio = meetingMessage.isAudio,
                meetingNumber = meetingMessage.meetingNumber,
                from = PersistentVariables.sipAccount,
                isAccept = isAccept
        )
        SipUtil.sendSipMessage(SipUtil.makeValidSipUri(meetingMessage.from!!), JsonUtil.toJson(enterMeetingReplyMessage)!!)

        Timber.i("是否接受了会议邀请：$isAccept")
        if (isAccept) {
            if (meetingMessage.isAudio == true) {
                // 语音会议
                ActivityUtil.getTopActivity()?.startService(Intent(ActivityUtil.getTopActivity(), OutgoingService::class.java).apply {
                    putExtra(Keys.OUTGOING_NUMBER, meetingMessage.meetingNumber)
                })
            } else {
                // 视频会议
                ActivityUtil.getTopActivity()?.startActivity(Intent(ActivityUtil.getTopActivity(), CameraActivity::class.java).apply {
                    putExtra(Keys.OUTGOING_NUMBER, meetingMessage.meetingNumber)
                })
            }
        }
    }

    /** 邀请会议的回应 */
    private fun enterMeetingReply(sipMessage: String) {
        val enterMeetingReplyMessage = JsonUtil.json2Bean(sipMessage, EnterMeetingReplyMessage::class.java)
        if (enterMeetingReplyMessage == null) {
            Timber.e("EnterMeetingReplyMessage消息无法解析，json = $sipMessage")
            return
        }

        val isAcceptDesc = if (enterMeetingReplyMessage.isAccept == true) "授受了" else "拒绝了"
        ActivityUtil.getTopActivity()?.toast("${enterMeetingReplyMessage.from}${isAcceptDesc}${enterMeetingReplyMessage.meetingNumber}会议的邀请")
    }

    /** 退出会议 */
    private fun exitMeeting(sipMessage: String) {
        ActivityUtil.getTopActivity()?.toast("收到退出会议的消息：$sipMessage")

        val meetingMessage = JsonUtil.json2Bean(sipMessage, MeetingMessage::class.java)
        if (meetingMessage == null) {
            Timber.e("MeetingMessage消息无法解析，json = $sipMessage")
            return
        }

        if (meetingMessage.isAudio == true) {
            TODO("退出语音会议")
        } else {
            TODO("退出视频会议")
        }
    }

    private fun showLog(responseString: String) {
        // {"action":"showLog","isShowLog":"false"}
//        val showLog: ShowLog? = JsonUtil.json2Bean(responseString, ShowLog::class.java)
//        Timber.setLogSwitch(showLog?.isShowLog ?: false)
    }

    private fun processGetFile(responseString: String) {
        // {"action":"getFile","fileType":"音频","attachmentid":"1","title":"zfy003_2020_09_10_1230.aac", "sipAccount":"20012"}
        Timber.i("收到上传文件请求消息：$responseString")
        /*val getFile = JsonUtil.json2Bean(responseString, GetFile::class.java)
        if (getFile?.sender != null && getFile.title != null && getFile.fileType != null && getFile.attachmentid != null) {
            EventBus.getDefault().post(Message.obtain(null, Whats.FILE_UPLOAD_REQUEST, getFile))
        } else {
            Timber.fe("收到的上传文件参数有误：$responseString")
            SipUtil.sendUploadFileResult(getFile, false, "参数错误，不能有空参数，参数为： $responseString")
        }*/
    }

    private fun processMeetingType(responseString: String, remoteParty: String?) {
        if (remoteParty == null) return
        // {"action":"changeMeetingType","type":"audio"}
        Timber.i("收到改变会议类型消息：$responseString")
        /*JsonUtil.json2Bean(responseString, ChangeMeetingType::class.java)?.let {
            NgnProxyVideoProducer.isAudioMeeting = it.type == "audio"
            if (!NgnProxyVideoProducer.isAudioMeeting) {
                // {"action":"signalLevel","ipphone":"150000","signalLevel":"4"}
                App.sSignalReceiverSet.add(remoteParty)
                App.sendSignalMessage(remoteParty)
                Timber.i("发送了信号消息")
            } else {
                App.sSignalReceiverSet.remove(remoteParty)
            }
        }*/
    }

    private fun rotate(degree: Int) {
        when (degree) {
            0 -> {
                NgnEngine.getInstance().configurationService.putBoolean(NgnConfigurationEntry.ROTATE180, false, true)
                //App.restartApp()  // 改变视频方向后需要挂断电话后重新拨号，使新的视频方向生效
            }
            180 -> {
                NgnEngine.getInstance().configurationService.putBoolean(NgnConfigurationEntry.ROTATE180, true, true)
               // App.restartApp()   // 改变视频方向后需要挂断电话后重新拨号，使新的视频方向生效
            }
        }
    }

    private fun sendSerialNumber(remoteParty: String?) {
        if (remoteParty == null) return
        // 查询json：{"action":"getSimSerialNumber"}
        // 发送json：{"action":"getSimSerialNumber","simSerialNumber":"89860440191890114934"}
//        val serialNumber = SimSerialNumber("getSimSerialNumber", SimCardUtil.getSimSerialNumber())
//        SipUtil.sendSipMessage(remoteParty, JsonUtil.toJson(serialNumber)!!)
    }

    /** 上传日志 */
    private fun uploadLog(json: String) {
        /*val upLoadLogEvent = JsonUtil.json2Bean(json, UpLoadLogEvent::class.java)
        if (upLoadLogEvent?.type != FileUploadUtil.ALL
                && upLoadLogEvent?.type != FileUploadUtil.ERROR
                && upLoadLogEvent?.type != FileUploadUtil.INFO) {
            Timber.e("上传日志命令不合法，json = $json")
            return
        }
        FileUploadUtil.uploadLogFiles(upLoadLogEvent.type)*/
    }

    /** 设置系统时间 */
    @SuppressLint("SimpleDateFormat")
    private fun setTime(json: String) {
        // {"action":"setBallDate","date":"2019-09-28 11:39:50"} // 时间格式：yyyy-MM-dd HH:mm:ss
        /*val setTimeEvent = JsonUtil.json2Bean(json, SetTimeEvent::class.java)
        if (setTimeEvent?.date == null) {
            Timber.e("设置时间的sip命令格式有误，无法转换为JavaBean，json = $json")
            return
        }

        val time = SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(setTimeEvent.date)
        time?.let {
            SystemClock.setCurrentTimeMillis(it.time)
        }*/
    }

    /**  通过Sip发送Gps定位信息给服务器 */
    private fun sendGps(remoteParty: String?, json: String) {
        /*if (remoteParty == null) return
        // 查询json: {"action":"getCoordinate","sender":"10001","ball":"20001"}
        val getGpsInfoEvent = JsonUtil.json2Bean(json, GetGpsInfoEvent::class.java)
        if (getGpsInfoEvent == null || TextUtils.isEmpty(getGpsInfoEvent.action) || TextUtils.isEmpty(getGpsInfoEvent.sender) || TextUtils.isEmpty(getGpsInfoEvent.ball)) {
            Timber.e("获取Gps信息的命令不合法，json = $json")
            return
        }

        val gpsJson = StorageUtil.getStringOrNull(Keys.GPS_INFO)
        val serverSipAccount = "pttservice" // 服务器使用的sip账号
        if (!gpsJson.isNullOrBlank()) {
            Timber.e("读取到保存的Gps信息：$gpsJson")
            val gpsInfo = JsonUtil.json2Bean(gpsJson, GpsInfo::class.java)
            if (gpsInfo != null) {
                gpsInfo.action = getGpsInfoEvent.action
                gpsInfo.sender = getGpsInfoEvent.sender ?: serverSipAccount // 如果没有发送者，则使用服务器的sip账号
                gpsInfo.ball = getGpsInfoEvent.ball

                // 发送json：{"action":"getCoordinate","sender":"10001","ball":"20001","latitude":"27.0293", "longitude":"112.35986","altitude":"15","localtime":"2019-01-01 01:00:00"}
                SipUtil.sendSipMessage(remoteParty, JsonUtil.toJson(gpsInfo)!!)
                return
            }
        }

        // 能走到这里的，说明没有Gps定位信息，则返回定位信息为0
        val gpsInfo = GpsInfo(getGpsInfoEvent.action, getGpsInfoEvent.sender ?: serverSipAccount, getGpsInfoEvent.ball, "0", "0", "0", "0")
        SipUtil.sendSipMessage(remoteParty, JsonUtil.toJson(gpsInfo)!!)*/

    }

    /**  通过Sip发送视频分辨率给服务器 */
    private fun sendVideoSize(remoteParty: String?) {
        /*if (remoteParty == null) return
        // 查询json：{"action":"getVideoSize"}
        val videoSize = Utils.getCurrentVideoSize()
        // 发送json：{"action":"getVideoSize","size":"VGA"}
        SipUtil.sendSipMessage(remoteParty, JsonUtil.toJson(GetVideoSize(size = videoSize))!!)*/
    }

    /**  通过Sip发送版本号给服务器 */
    private fun sendVersion(remoteParty: String?) {
        if (remoteParty == null) return
        // 查询json：{"action":"getAppVersion"}
        val version = GetVersion("getAppVersion", App.getVersionName(), App.getVersionCode().toString())
        // 发送json：{"action":"getAppVersion","versionCode":"201909290","versionName":"2.0.6"}
        SipUtil.sendSipMessage(remoteParty, JsonUtil.toJson(version)!!)
    }

    /** 设置视频大小  */
    private fun setVideoSize(json: String) {
        // 改变视频分辨率的消息JSON格式：{"videoSize":"720P"} ，有4个取值：1080P、720P、VGA、CIF
        /*val videoSizeBean = JsonUtil.json2Bean(json, VideoSizeBean::class.java)
        if (videoSizeBean == null || TextUtils.isEmpty(videoSizeBean.size)) {
            Timber.d("设置视频大小json无法解析，json = $json")
            return
        }
        if (!VideoSizeUtil.videoSizeMap.containsKey(videoSizeBean.size)) {
            Timber.e("未知的视频分辨率：${videoSizeBean.size}")
            return
        }
        VideoSizeUtil.setVideoSize(videoSizeBean.size!!)*/
    }

    /** 处理退出会议 */
    private fun processExitGroup(json: String) {
        // 服务器把人踢了之后会自动断开连接，不需要手动挂断这个会议，会自动断开
        /*Timber.e("处理退组事件")
        val exitGroup = JsonUtil.json2Bean(json, ExitGroup::class.java)
        val ballId = StorageUtil.getBallId()
        // 这个Json是接收到有人被踢出会议了，但是不是球机被踢出了会话，需要通过ipphoe来判断
        if (exitGroup == null || exitGroup.group.isNullOrEmpty() || exitGroup.ipphone.isNullOrBlank()) {
            Timber.d("退组命令无法解析，json = $json")
            return
        }

        if (exitGroup.ipphone != "2${ballId?.substring(1)}") {
            return // 不是球机被踢
        }

        Utils.queryAllAudioConference { sessionId, number ->
            if (exitGroup.group == number) {
                Utils.hangupAudioConference(sessionId, number)
            }
        }*/
    }

    fun processMSRPEvent(intent: Intent) {
        val args = intent.getParcelableExtra<NgnMsrpEventArgs>(NgnMsrpEventArgs.EXTRA_EMBEDDED)
        if (args == null) {
            Timber.e("Invalid event args")
            return
        }
        if (args.eventType == NgnMsrpEventTypes.DATA) {
            val session = NgnMsrpSession.getSession(args.sessionId)
            if (session == null) {
                Timber.e("Failed to find MSRP session with id=" + args.sessionId)
                return
            }
            val content = intent.getByteArrayExtra(NgnMsrpEventArgs.EXTRA_DATA)
            val event = NgnHistorySMSEvent(NgnUriUtils.getUserName(session.remotePartyUri), NgnHistoryEvent.StatusType.Incoming)
            event.content = content?.let { String(it) } ?: NgnStringUtils.nullValue()
            mEngine.historyService.addEvent(event)
        }
    }

    fun processInviteEvent(intent: Intent) {
        val args = intent.getParcelableExtra<NgnInviteEventArgs>(NgnEventArgs.EXTRA_EMBEDDED)
        if (args == null) {
            Timber.fe("Invalid event args")
            return
        }

        val mediaType = args.mediaType
        Timber.fi("收到通话事件：mediaType = ${mediaType}, eventType = ${args.eventType}")

        if (!NgnMediaType.isAudioVideoType(mediaType)) {
            Timber.fe(Exception("不是音视频类型，不处理, mediaType = $mediaType"))
            // 其它类型有：NgnMediaType.isFileTransfer(mediaType)、NgnMediaType.isChat(mediaType)
            return
        }

        when (args.eventType) {
            NgnInviteEventTypes.INCOMING -> { // 有来电，还没接。当我们接通电话后会走一个INCALL状态，表示已接通
                val session = NgnAVSession.getSession(args.sessionId) ?: return
                mEngine.soundService.startRingTone()
                if (!mWakeLock.isHeld) {
                    mWakeLock.acquire(10)
                }
                if (SipUtil.isVideoCall(session)) { // 有视频电话打进来
                    ActivityUtil.getTopActivity()?.startActivity<CameraActivity>(Keys.AV_SESSION_ID to args.sessionId)
                }
            }
            NgnInviteEventTypes.INPROGRESS -> { } // 正在拨出，当拨会议号成功时会走一个INCALL状态，表示已接通
            NgnInviteEventTypes.RINGING -> {
                mEngine.soundService.startRingBackTone()
            }
            NgnInviteEventTypes.CONNECTED, NgnInviteEventTypes.EARLY_MEDIA -> { // 不论是拨出还是接听，当电话接通时会走这里
                mEngine.soundService.stopRingBackTone()
                mEngine.soundService.stopRingTone()
            }
            NgnInviteEventTypes.TERMWAIT, NgnInviteEventTypes.TERMINATED -> {
                mEngine.soundService.stopRingBackTone()
                mEngine.soundService.stopRingTone()
            }
            else -> {
            }
        }
    }

    /** 处理注册事件 */
    fun processRegisterEvent(intent: Intent) {
        val args: NgnRegistrationEventArgs = intent.getParcelableExtra(NgnEventArgs.EXTRA_EMBEDDED) ?: return
        /*
	     * 注册事件流程：
		 * 点击注册，会收到事件：REGISTRATION_INPROGRESS（正在注册）、REGISTRATION_OK（注册成功）、UNREGISTRATION_OK（解除注册成功/注册失败），没网时注册收不到任何事件
		 * 点击退出注册，会收到事件：UNREGISTRATION_INPROGRESS（正在退出注册）、UNREGISTRATION_OK（解除注册成功/注册失败）
		 * 由此可见，UNREGISTRATION_OK即表示注册失败，也表示解除注册成功，而REGISTRATION_NOK（注册失败）、UNREGISTRATION_NOK（解除注册失败）这两个事件并没有被使用到
		 * 那解除注册时是否会有解除失败的情况？ 因为不会有。如果有的话，也只能是用UNREGISTRATION_OK来代替
		 */
        Timber.i("收到注册事件：${args.eventType}")
        when (args.eventType) {
            NgnRegistrationEventTypes.REGISTRATION_INPROGRESS -> {
                Timber.fi("正在注册")
                isRegistering = true
                isUnregistering = false
            }
            NgnRegistrationEventTypes.UNREGISTRATION_INPROGRESS -> {
                Timber.fi("正在解除注册")
                isRegisterOk = false
                isRegistering = false
                isUnregistering = true
            }
            NgnRegistrationEventTypes.REGISTRATION_OK -> { Timber.i("注册成功"); isRegisterOk = true }
            NgnRegistrationEventTypes.UNREGISTRATION_OK -> { // 这个状态即表示注册成功，也表示注册失败，也表示解除注册成功
                when {
                    isRegistering -> {
                        isRegistering = false
                        // 如果之前注册成功了，而且现在用户没注销，则说明现在是掉线了，则重新注册
                        if (isRegisterOk) {
                            if (PersistentVariables.isLogout) {
                                Timber.fi("用户注销了，正常断开了注册")
                                isRegisterOk = false
                            } else {
                                Timber.fw(Exception("用户没注销，sip掉线了，准备开始重新注册"))
                                // 有时发现，虽然收到这个解除注册了，但是Engine是启动状态，SipService也是注册状态，所以先手动停止。
                                EngineHelper.stopEngine {
                                    againRegistration()
                                }
                            }
                        } else {
                            Timber.fi("正常注册，但是注册失败")
                        }
                    }
                    isUnregistering -> {
                        Timber.fi("解除注册成功")
                        isUnregistering = false
                        isRegisterOk = false
                    }
                    else -> {
                        Timber.fi("不知道在一个什么鬼状态下解除注册了")
                    }
                }
            }
            NgnRegistrationEventTypes.REGISTRATION_NOK -> Timber.fi("注册失败222")      // 这个状态没有使用到
            NgnRegistrationEventTypes.UNREGISTRATION_NOK -> Timber.fi("解除注册失败") // 这个状态没有使用到
            else -> Timber.fi("奇怪的注册状态：${args.eventType}")
        }

        EventBus.getDefault().post(Message.obtain(null, EventBusEventType.REGISTER_STATE, args.eventType))
    }

    /** 重新注册 */
    private fun againRegistration(isRightNowRegister: Boolean = false) {
        if (PersistentVariables.isLogout) {
            registerHandler.removeCallbacksAndMessages(null)
            Timber.fe(Exception("重新注册函数被调用，但账号已被注销"))
            return
        }

        if (isRegistering) {
            Timber.fw("已经正在注册了，又被调用了一次注册函数")
            return
        }
        isRegistering = true

        val delay = when {
            isRightNowRegister -> 0L  // 如果是要立马注册，则不延迟
            retryCount++ < 3 -> 2000L // 如果注册次数不够3次，则2秒后再试
            else -> {                 // 如果注册次数3次以上，则10秒后再试
                retryCount = 0
                10_000L
            }
        }

        if (isRightNowRegister) {
            Timber.fi("立马重新注册")
            EngineHelper.stopEngine {
                registerHandler.removeCallbacksAndMessages(null)
                registerHandler.sendEmptyMessageDelayed(0, delay)
                Unit
            }
        } else {
            Timber.fi("第${retryCount}次重新注册")
            registerHandler.removeCallbacksAndMessages(null)
            registerHandler.sendEmptyMessageDelayed(0, delay)
        }
    }

    override fun handleMessage(msg: Message): Boolean {
        Timber.fi("handleMessage函数被执行了")
        if (!Utils.hasActiveNetwork()) {
            Timber.fw("没有可用网络，无法注册")
            isRegistering = false
            againRegistration()
            return true
        }

        if (PersistentVariables.isLogout) {
            Timber.fw("重新注册函数无法调用（handleMessage），因为账号已被注销")
            isRegistering = false
            return true
        }

        Timber.fi("在handleMessage中马上开始执行再次注册")
        SipRegisterHelper.register { registerSuccess, failMsg ->
            isRegistering = false
            if (registerSuccess) {
                Timber.fi("重新注册成功！")
            } else {
                Timber.fw("重新注册失败：$failMsg")
                againRegistration()
            }
        }
        return true
    }

    /** 马上注册 */
    @Subscribe
    fun rightNowRegister(message: Message) {
        if (message.what == Whats.RIGHT_NOW_REGISTER) {
            againRegistration(true)
        }
    }

    /** 点击了登录按钮 */
    @Subscribe
    fun onClickLoginButton(message: Message) {
        if (message.what == Whats.ON_CLICK_LOGIN_BUTTON) {
            registerHandler.removeCallbacksAndMessages(null)
        }
    }

    /** 点击了注销按钮 */
    @Subscribe
    fun onClickLogoutButton(message: Message) {
        if (message.what == Whats.ON_CLICK_LOGOUT_BUTTON) {
            registerHandler.removeCallbacksAndMessages(null)
        }
    }

    /**释放资源  */
    fun onDestroy() {
        if (mWakeLock.isHeld) {
            mWakeLock.release()
        }
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this)
        }
        registerHandler.removeCallbacksAndMessages(null)
        TalkbackGroupHelper.hangUpAll()
    }

}
